案例名称:课程表查询系统

案例编号:C5

涉及的知识点编号:

涉及的基础实验编号:

作者:中原工学院 刘凤华

一、 项目整体概述

根据登录信息获取校园网上的课程信息并个性化形式显示,方便在校学生查看本班课程表和个人课程信息。

二、 方案设计

主要技术点包括:创建工程、网络服务技术应用、 模拟校园网登录、 多线程应用、 AsyncTask异步处理技术应用、jsoup爬取网站信息技术应用等

三、 系统开发步骤

1、任务编号:C5-001 加载项目工程

1.1、相关知识点

Android的目录结构

1.2、任务描述

前置任务:无

业务模块:主视图界面

创建一个新的Android工程。

任务类型:按要求写代码(功能实现)

1.3、详细实现步骤

创建一个Android项目。

  • 取名”KB”。
  • 在工程res文件夹中新建drawable文件夹。
  • 将当前实训场景中的素材文件夹中的素材复制入drawable文件夹。

2、任务编号:C5-002 发布Android项目

2.1、相关知识点

发布Android项目录

2.2、任务描述

前置任务:C5-001

业务模块:主视图界面

1、修改项目图标并通过Eclipse部署项目。

任务类型:按要求写代码(功能实现)

2、将APK文件通过adb指令部署入模拟器或手机中。

任务类型:按要求写代码(功能实现)

2.3、详细实现步骤

1、修改项目图标并通过Eclipse部署项目。

  • 通过AndroidMainfest.xml文件修改图标资源。
  • 设定当前应用的图标为tb.png。
  • 运行模拟器。
  • 将当前应用部署入模拟器。

2、 将APK文件通过adb指令部署入模拟器或手机中。

  • 在Windows的控制台上通过adb指令安装APK文件。
  • APK文件件:素材->APK文件夹中的文件。

3、任务编号:C5-003 构建主界面布局

3.1、相关知识点

线性布局-LinearLayout

3.2、任务描述

前置任务:C5-002

业务模块:主视图界面

任务类型:按要求写代码(功能实现)

3.3、参考效果

图1-1

图1-2

3.4、详细实现步骤

1、构建课程表主界面。

  • 主界面布局文件名:layout_main.xml。
  • 主界面布局选用:LinearLayout。
  • 在主界面布局文件中增加两个View:

  • 在主界面布局文件中增加两个View:

    • 第一个视图(LinearLayout):TextView+Button
    • 第二个视图:ViewPager
    • ViewPager必须出现在第一个视图LinearLayout的下方
  • 周一至周五显示课程信息(共五大节,根据系统时间自动切换界面)(如图1-1)

  • 周六周日显示无课界面(如图1-2)

4、任务编号:C5-004-1 构建成绩显示页面布局

4.1、相关知识点

线性布局-LinearLayout

4.2、任务描述

前置任务:C5 -003

业务模块:主视图界面

构建课程表成绩页面布局

任务类型:按要求写代码(功能实现)

4.3、参考效果

图1-3

4.4、详细实现步骤

欢迎页面布局:

  • 布局文件名:activity_grade.xml。
  • 界面布局选用:LinearLayout。
  • 背景图片设为w01.Jpg
  • 在布局文件中增加40个LinearLayout:
    • 每一个LinearLayout中放四个TextView,分别用来显示从校网上获取到的信息。如“学期”“课程名”“成绩”“学分”。
    • 四个TextView分别占不同比重,分别是10%,60%,15%,15%,用来在显示信息的时候对齐。

5、任务编号:C5-004-2 构建登录页面布局

5.1、相关知识点

线性布局-LinearLayout

5.2、任务描述

前置任务:C5 -003

业务模块:主视图界面

构建课程表成绩页面布局

任务类型:按要求写代码(功能实现)

5.3、参考效果

图1-4

5.4、详细实现步骤

构建登录页面布局:

  • 布局文件名:activity_login.xml。
  • 界面布局选用:LinearLayout。
  • 界面布局背景图片:background_login。
  • 在布局文件中增加两个RelativeLayout:
    • 第一个RelativeLayout中增加两个TextView和EditView,一个Button。 TextView为提示语“学号”和“姓名”,Button为登录按钮。
    • 第二个RelativeLayout中放一个TextView ,文本设为“忘记密码”,增加点击事件“forgetPwd”。

6、任务编号:C5-004-3 构建个人信息页面布局

6.1、相关知识点

线性布局-LinearLayout

6.2、任务描述

前置任务:C5-003

业务模块:主视图界面

任务类型:按要求写代码(功能实现)

6.3、参考效果

图1-5

6.4、详细实现步骤

构建个人信息页面布局:

  • 布局文件名:activity_person_info.xml。
  • 界面布局选用:LinearLayout。
  • 在布局文件中增加四个RelativeLayout:
    • 每个RelativeLayout中都添加两个TextView,第一个显示提示信息,例:“姓名”
    • 第二个用来存放从校网获取到的个人信息,如:“张三”。

7、任务编号:C5-004-4 构建关于我们页面布局

7.1、相关知识点

 线性布局-LinearLayout

7.2、任务描述

前置任务:PRJ-EC-MD-03

业务模块:主视图界面

任务类型:按要求写代码(功能实现)

7.3、参考效果

图1-6

7.4、详细实现步骤

构建关于我们页面布局:

  • 布局文件名:activity_about.xml。
  • 界面布局选用:LinearLayout。
  • 在布局文件中增加一个TextView:
    • TextView中设文字“************”

8、任务编号:C5-004-5 构建欢迎页面布局

8.1、相关知识点

线性布局-LinearLayout

8.2、任务描述

前置任务:C5-003

业务模块:主视图界面

任务类型:按要求写代码(功能实现)

8.3、参考效果

图1-7

8.4、详细实现步骤

构建欢迎页面布局:

  • 布局文件名:activity_splash.xml。
  • 界面布局选用:RelativeLayout。
  • 在布局文件中增加一个TextView:
    • 背景设置为图片tb.jpg
    • TextView中设欢迎语“掌上课程,方便你的生活!”

9、任务编号:C5-004-6 构建设置页面布局

9.1、相关知识点

线性布局-LinearLayout

9.2、任务描述

前置任务:C5-003

业务模块:主视图界面

任务类型:按要求写代码(功能实现)

9.3、详细实现步骤

建设置页面布局。

  • 布局文件名:activity_more.xml。
  • 界面布局选用:LinearLayout。
  • 在布局文件中增加两个RelativeLayout:
    • 第一个RelativeLayout中分别添加三个TextView和ImageView,即“个人信息”“切换账号”“查询成绩”,点击可进行页面跳转。
    • 第二个RelativeLayout中分别添加三个TextView和ImageView,即“帮助与反馈”“刷新课程”“关于我们”,点击可进行页面跳转。
    • 第二个RelativeLayout下方放置一个注销按钮。

10、任务编号:C5-005 解析数据源

10.1、相关知识点

jsoup包抓取网页上的数据

xUtils开源框架

10.2、任务描述

前置任务:无业务模块:数据解析

模拟登录,从校网获取到个人信息,课程信息和成绩信息。

任务类型:按要求写代码(功能实现)

10.3、详细实现步骤

1、第一步需要模拟登录

(1).检查网络是否打开

(2)在联网的情况下开启一个异步线程去请求登录。模拟登陆不能放在主线程,会阻塞主线程。

检查网络是否打开:

public void login(View view) {
    if (NetWorkUtil.isNetworkConnected(this)) {
        new LoginTask().execute\(usernameEditText.getText().toString()
             .trim(), passwordEditText.getText().toString().trim\());
    } else {
         Toast.makeText(this, "当前无网络,请打开网络连接", Toast.LENGTH_SHORT).show();
    }
}

异步线程:

/*采用异步技术实现登陆验证(学生登陆验证) */

public class LoginTask extends AsyncTask<String, Void, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dialog.show();
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            return login(params[0], params[1]);
        } catch (IOException e) {
            Log.e("xkb", "" + e.getMessage());
            // e.printStackTrace();
        }
        return "";
    }

    protected void onPostExecute(String result) {
        dialog.dismiss();
        if (result.equals("success")) {
            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
            startActivity(intent);
            LoginActivity.this.finish();
        }else {
            Toast.makeText(LoginActivity.this, "登录失败,请核对学号和密码", Toast.LENGTH_LONG).show();
        }
    }
}

模拟登录:

public String login(String username, String password) throws IOException {
    String cookie = new String();
    String tag = "";
    // 验证用户名和密码
    Connection con = Jsoup.connect(Util.LOGIN_URL)
            .data("userName", username).data("password", password)
            .timeout(5000);
    con.post();
    cookie = con.response().cookie("iPlanetDirectoryPro");
    if (cookie != null) {
        /* 获取个人信息 课程信息*/
        getUserInfo(cookie);
        tag = "success";
    }
    return tag;
}

2.第2步开始获取想要的信息

(1).获取个人信息:需要保存网页中的cookie

/* 获取个人信息*/
private void getUserInfo(String cookie) throws IOException {
        // 开始获取个人信息
        Connection con = Jsoup.connect(Util.USER_INFO_URL)
                .cookie("iPlanetDirectoryPro", cookie).timeout(5000);
        //保存网页中的cookie
        String cookie2 = con.response().cookie("JSESSIONID");
        //获取到的信息保存在文档Document中
        Document yuanma = con.get();
        //通过筛选来抓取有用的信息
        Elements div = yuanma.select("div.composer"); 
        Elements lis = div.select("li");
        // 存放个人信息的数组
        String[] str = new String[10];        
        int i = 0;
        for (Element li : lis) {
            String personInfo = li.text();
            str[i] = personInfo;
            i++;
        }
        editor.putString("name", str[0].substring(0, str[0].indexOf(",")).trim());//名字放入到key值为”name”的键值对中
        editor.putString("number", str[2].substring(str[2].indexOf(":") + 1).trim()); //学号放入到key值为”number”的键值对中
        editor.putString("class", str[3].substring(str[3].indexOf(":") + 1).trim()); //班级放入到key值为”class”的键值对中                
        editor.putString("depart", str[4].substring(str[4].indexOf(":") + 1).trim()); //院系放入到key值为”depart”的键值对中

        editor.commit();    
}

(2).获取课程信息和成绩信息和获取个人信息步骤一样,须模拟登陆保存cookie才可以抓取。

而抓取的方式有所不同。

获取课程信息:

Document doc = con.get();
//课程信息在表格table_kc中
Elements kechengbiaoElement = doc.select("table.table_kc");
//课程保存在包含br>标签的div标签中
Elements kechengElements = kechengbiaoElement.select("div:has(br)");

获取成绩信息:

Document doc = con.get();
Elements kechengbiaoElement = doc.select("table.table_kscj");
//成绩保存在包含td标签的tr标签中
Elements trs = kechengbiaoElement.select("tr");
for (int i = 0; i < trs.size(); i++) {
        Elements tds = trs.get(i).select("td");
        //只抓取一个tr标签中的第2.3.5.8个td标签,即学期,课程,成绩和学分
        String text= tds.get(1).text();
        String text1= tds.get(2).text();
        String text2= tds.get(4).text();
        String text3= tds.get(7).text();
}

11、任务编号:C5-006 解析系统时间

11.1、相关知识点

xUtils开源框架

11.2、任务描述


置任务:无

业务模块:解析当前系统时间,并转换为需要的格式

任务类型:按要求写代码(功能实现)

11.3、详细实现步骤

第一步需要获取当前系统时间

/*获取当前周是第几周*/
@SuppressLint("SimpleDateFormat")
public static long getCurrentWeek() {
    Date data = new Date();//获取当前系统时间
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//解析时间格式
    long to = 0;
    long from = 0;
    String currentData = df.format(data);
    try {
        from = df.parse(Util.SCHOOL_START_DATE).getTime();
        to = df.parse(currentData).getTime();
    } catch (ParseException e) {
        e.printStackTrace();
    }
    long currentWeek = ((to - from) / (1000 * 60 * 60 * 24) + 1) / 7 + 1;// 计算当前周
    return currentWeek;
}

/* 获取今天是星期几*/
public static String getCurrentDay() {
    long time=System.currentTimeMillis();  
        Date date=new Date(time);  
        SimpleDateFormat format=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 EEEE");  
        format=new SimpleDateFormat("EEEE");  //只获取周几(形式是星期*)
        return format.format(date);        
}

12、任务编号:C5-007 数据封装

12.1、相关知识点

将数据封装入对象中

12.2、任务描述


置任务:C5-005,C5-006

业务模块:数据解析加封装

设计并定义保存数据的实体类。

任务类型:按要求写代码(功能实现)

12.3、详细实现步骤

1、设计并定义保存课程数据的CourseEntity实体类

  • 实体有course, teacher, week, classroom,重写他们的get和set方法

2、设计并定义保存课程数据的BaseEntity实体类

  • 实体有Id,重写他的get和set方法

3、用Adapter适配器显示每一天课程。

  • CourseAdapter继承BaseAdapter:

    • 先获取到页面布局
    // 如果缓存convertView为空,则需要创建View
    if (convertView == null) {
                holder = new ViewHolder();
                // 根据自定义的Item布局加载布局
                convertView = mInflater.inflate(R.layout.list_item, null);
                holder.jieci = (TextView) convertView.findViewById(R.id.textView01);
                holder.teacher = (TextView) convertView.findViewById(R.id.textView02);
                holder.week = (TextView) convertView.findViewById(R.id.textView03);
                holder.course = (TextView) convertView.findViewById(R.id.textView04);
                holder.classroom = (TextView) convertView.findViewById(R.id.textView05);
    
    • 根据周几来显示相应的课程信息
    holder.jieci.setText(jieciStrings[position]);
    holder.course.setText(mDatas.get(position).getCourse());
    holder.teacher.setText(mDatas.get(position).getTeacher());
    holder.week.setText(mDatas.get(position).getWeek());
    holder.classroom.setText(mDatas.get(position).getClassroom());
    
  • MyPagerAdapter继承FragmentPagerAdapter

    • 重写所有的方法

13、任务编号:C5-008 课程信息显示

13.1、相关知识点

SimpleAdapter

13.2、任务描述

前置任务:C5-007

业务模块:课程显示

根据星期几显示相应课程

任务类型:按要求写代码(功能实现)

13.3、详细实现步骤

1、 初始化屏幕(包括周一至周五五个页面)。

private void init() {
        // 初始化屏幕宽度
        DisplayMetrics outmMetrics = new DisplayMetrics();
        getWindow().getWindowManager().getDefaultDisplay().getMetrics(outmMetrics);
        screenWidth = outmMetrics.widthPixels;
        initView();
        // 设置title : 周次
        currentWeek = DateUtil.getCurrentWeek();
        courseText.setText("课程表(第" + currentWeek + "周)");
        Log.i("chen", "currentWeek--->" + currentWeek);
}
private void initView() {
        // 初始化五个页面
        Fragment02 fragment0 = new Fragment02();
        Fragment01 fragment1 = new Fragment01(0);
        Fragment01 fragment2 = new Fragment01(1);
        Fragment01 fragment3 = new Fragment01(2);
        Fragment01 fragment4 = new Fragment01(3);
        Fragment01 fragment5 = new Fragment01(4);
        Fragment02 fragment6 = new Fragment02();
        fragments.add(fragment0);
        fragments.add(fragment1);
        fragments.add(fragment2);
        fragments.add(fragment3);
        fragments.add(fragment4);
        fragments.add(fragment5);
        fragments.add(fragment6);
        fragSize = fragments.size();

        // 初始化顶部tab
        firstTab = (LinearLayout) findViewById(R.id.tab_first);
        secondTab = (LinearLayout) findViewById(R.id.tab_second);
        thirdTab = (LinearLayout) findViewById(R.id.tab_third);
        fourTab = (LinearLayout) findViewById(R.id.tab_four);
        fiveTab = (LinearLayout) findViewById(R.id.tab_five);
        sixTab = (LinearLayout) findViewById(R.id.tab_six);
        sevenTab = (LinearLayout) findViewById(R.id.tab_seven);
        // 给tab设置点击事件
        firstTab.setOnClickListener(tabClickListener);
        secondTab.setOnClickListener(tabClickListener);
        thirdTab.setOnClickListener(tabClickListener);
        fourTab.setOnClickListener(tabClickListener);
        fiveTab.setOnClickListener(tabClickListener);
        sixTab.setOnClickListener(tabClickListener);
        sevenTab.setOnClickListener(tabClickListener);
        initTabUnderLine();
        firstText = (TextView) findViewById(R.id.text_first);
        secondText = (TextView) findViewById(R.id.text_second);
        thirdText = (TextView) findViewById(R.id.text_third);
        fourText = (TextView) findViewById(R.id.text_four);
        fiveText = (TextView) findViewById(R.id.text_five);
        sixText = (TextView) findViewById(R.id.text_six);
        sevenText = (TextView) findViewById(R.id.text_seven);
        courseText = (TextView) findViewById(R.id.text_course);
        moreText = (TextView) findViewById(R.id.text_more);
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        pagerAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
        viewPager.setAdapter(pagerAdapter);
        viewPager.setOnPageChangeListener(pageChangeListener);
        /**
         * 根据当前是星期几,来显示星期几的课程信息
         */
        setCurrentPage();
        viewPager.setOffscreenPageLimit(fragSize);
}

2.课程信息放入实体中显示

/* 根据当前是星期几,来显示星期几的课程信息*/
private void setCurrentPage() {
    // 获取当前星期几
    currentDay = DateUtil.getCurrentDay().toString().trim();
    Log.i("chen", "currentDay--->" + currentDay);
    if (currentDay.equals("星期日")) {
        viewPager.setCurrentItem(0);//如果是星期日,则设置显示第0个页面
    } else if (currentDay.equals("星期一")) {
        viewPager.setCurrentItem(1);
    } else if (currentDay.equals("星期二")) {
        viewPager.setCurrentItem(2);
    } else if (currentDay.equals("星期三")) {
        viewPager.setCurrentItem(3);
    } else if (currentDay.equals("星期四")) {
        viewPager.setCurrentItem(4);
    } else if (currentDay.equals("星期五")) {
        viewPager.setCurrentItem(5);
    } else if (currentDay.equals("星期六")) {
        Log.i("chen", "currentDay--->" + currentDay);
        viewPager.setCurrentItem(6);
    }
}

3.设置tab标题颜色

private void resetTabTextView() {
        firstText.setTextColor(getResources().getColor(R.color.black));
        secondText.setTextColor(getResources().getColor(R.color.black));
        thirdText.setTextColor(getResources().getColor(R.color.black));
        fourText.setTextColor(getResources().getColor(R.color.black));
        fiveText.setTextColor(getResources().getColor(R.color.black));
        sixText.setTextColor(getResources().getColor(R.color.black));
        sevenText.setTextColor(getResources().getColor(R.color.black));
}

14、任务编号:C5-009 个人信息显示

14.1、相关知识点

自定义适配器(简单)

14.2、任务描述

前置任务:C5-007

业务模块:个人信息

任务类型1:按要求写代码(功能实现)

14.3、参考效果

图1-5

14.4、详细实现步骤

1.先获取到页面布局

  • 初始化所有的控件。
private void initViews() {
        name = (TextView) findViewById(R.id.pinfo_name);
        num = (TextView) findViewById(R.id.pinfo_num);
        pclass = (TextView) findViewById(R.id.pinfo_class);
        yuanxi = (TextView) findViewById(R.id.pinfo_yuanxi);
        btnBack = (Button) findViewById(R.id.btn_back);
}

2.从保存信息的文档中取出所需信息,并放入页面显示

int MODE = MODE_PRIVATE;
SharedPreferences sharedPreferences = getSharedPreferences(Util.PREFERENCE_NAME, MODE);
name.setText(sharedPreferences.getString("name", ""));//名字保存在key值为”name”的键值对中
num.setText(sharedPreferences.getString("number", ""));//学号
pclass.setText(sharedPreferences.getString("class", ""));//学校类别(本专)
yuanxi.setText(sharedPreferences.getString("depart", ""));//院系

15、任务编号:C5-010 成绩信息显示

15.1、相关知识点

自定义控件以及信息取放

15.2、任务描述

前置任务:C5-007

业务模块:成绩显示

显示学期,课程,成绩和学分

1-1、 各控件所占宽度

1-2、 各布局的排版

任务类型:按要求写代码(功能实现)

15.3、参考效果

图1-3

15.4、详细实现步骤

1.获取到页面布局及相应控件

private void initViews() {
                back=(Button) findViewById(R.id.btn_back);//返回按钮
                TV1=(TextView) findViewById(R.id.tv1);
                TV2=(TextView) findViewById(R.id.tv2);
                TV3=(TextView) findViewById(R.id.tv3);
                TV4=(TextView) findViewById(R.id.tv4);
                TV5=(TextView) findViewById(R.id.tv5);
                TV6=(TextView) findViewById(R.id.tv6);
                TV7=(TextView) findViewById(R.id.tv7);
                TV8=(TextView) findViewById(R.id.tv8);
                TV9=(TextView) findViewById(R.id.tv9);
}

2.从保存信息的文档中拿出成绩信息,放入页面显示

int MODE = MODE_PRIVATE;
//获取到文档
SharedPreferences sharedPreferences = getSharedPreferences(Util.PREFERENCE_NAME, MODE);
//第一门课程的信息
TV1.setText(sharedPreferences.getString("chengjia"+1, ""));//学期
TV_1.setText(sharedPreferences.getString("chengjib"+1, ""));//课程名
TV_01.setText(sharedPreferences.getString("chengjic"+1, ""));//成绩
TV_111.setText(sharedPreferences.getString("chengjid"+1, ""));//学分
//第二门课程的信息
TV2.setText(sharedPreferences.getString("chengjia"+2, ""));//学期
TV_2.setText(sharedPreferences.getString("chengjib"+2, ""));//课程名
TV_02.setText(sharedPreferences.getString("chengjic"+2, ""));//成绩
TV_222.setText(sharedPreferences.getString("chengjid"+2, ""));//学分

results matching ""

    No results matching ""